package cn.eonshine.cuba.inf.modular.basic.service.impl;

import java.io.IOException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;

import cn.eonshine.cuba.inf.common.http.InfStatus;
import cn.eonshine.cuba.inf.common.http.Message;
import cn.eonshine.cuba.inf.common.util.DateUtils;
import cn.eonshine.cuba.inf.modular.basic.entity.Mapping;
import cn.eonshine.cuba.inf.modular.basic.mapper.MappingMapper;
import cn.eonshine.cuba.inf.modular.basic.service.IMappingService;
import cn.eonshine.cuba.inf.modular.common.IMappingCommon;
import cn.eonshine.cuba.inf.modular.security.server.IKeyService;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;

/**
 * <p>
 * Mapping（对照表） 服务实现类
 * </p>
 *
 * @author Alan
 * @since 2018-08-09
 */
@Service
@Transactional
public class MappingServiceImpl extends ServiceImpl<MappingMapper, Mapping> implements IMappingService {
	@Autowired
	private IKeyService keyService;
	
	@Override
	public Message insertMapping(Message message) {
		Message msg = new Message();
		String decryptServerPubKey = null; // 明文服务端的PubKey
		int status = InfStatus.INF_ERROR;
		try {
			String clientMsg = keyService.getServerDecryptInfo(message.getMsg());
			List<Mapping> maps = JSONUtil.toList(JSONUtil.parseArray(clientMsg), Mapping.class);

			int isInsert=0;
			for (Mapping map : maps) {
				boolean isExist=false;
				if(StringUtils.isNotBlank(map.getId())) {
					Mapping  mapOne=getById(map.getId());
					if(mapOne != null ) {
						if(map.getCreateDate() == null) {
							map.setCreateDate(mapOne.getCreateDate());
						}
						if(StringUtils.isBlank(map.getCreateBy())) {
							map.setCreateBy(mapOne.getCreateBy());
						}
						isExist = true;
					}
				}else if(StringUtils.isNotBlank(map.getLsmsId())){
					Mapping  mapOne=getOne(new QueryWrapper<Mapping>().eq("lsms_id", map.getLsmsId()));
					if(mapOne != null ) {
						map.setId(mapOne.getId());
						if(StringUtils.isBlank(map.getDmz1())) {
							map.setDmz1(map.getDmz1());
						}
						if(map.getCreateDate() == null) {
							map.setCreateDate(mapOne.getCreateDate());
						}
						if(StringUtils.isBlank(map.getCreateBy())) {
							map.setCreateBy(mapOne.getCreateBy());
						}
						isExist = true;
					}
				}
				boolean isSuccess = false;
				
				
				Date newDate = DateUtils.getCubaDate(Calendar.getInstance().getTime());
				if(map.getUpdateDate() == null) {
					map.setUpdateDate(newDate);
				}
				if(map.getCreateDate() == null) {
					map.setCreateDate(newDate);
				}
				if(StringUtils.isBlank(map.getCreateBy()) 
						&& StringUtils.isNotBlank(map.getUpdateBy())) {
					map.setCreateBy(map.getUpdateBy());
				}
				if(isExist) {
					this.baseMapper.updateById(map);
					isSuccess = true;
				}else {
					if(map.getCreateDate() == null) {
						map.setCreateDate(newDate);
					}
					this.baseMapper.insert(map);
					isSuccess = true;
				}
				if(isSuccess) {
					isInsert++;
				}
			}

	        // 将服务端的PubKey解密成明文
	     	decryptServerPubKey = keyService.getServerDecryptInfo(message.getPubKey());
	     	// 将客户端的PubKey加密成密文
	     	String localClientPubKey = keyService.getLocalPubKeyBase64();
	     	String cryptePubKey = keyService.getServerEncryptInfo(localClientPubKey, decryptServerPubKey);
	     	message.setPubKey(cryptePubKey);
			if(isInsert>0) {
				msg.setFlag(InfStatus.SAVE_STATUS_SUCESS);
			}else {
				msg.setFlag(InfStatus.SAVE_STATUS_FAIELD);
			}
			msg.setCount(isInsert);
			status = InfStatus.INF_OK;
		} catch (UnrecoverableKeyException e) {
			e.printStackTrace();
			msg.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			status = InfStatus.INF_ERROR;
			msg.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		} catch (KeyStoreException e) {
			e.printStackTrace();
			msg.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			status = InfStatus.INF_ERROR;
			msg.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			msg.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			status = InfStatus.INF_ERROR;
			msg.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		} catch (CertificateException e) {
			e.printStackTrace();
			msg.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			status = InfStatus.INF_ERROR;
			msg.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		} catch (IOException e) {
			e.printStackTrace();
			msg.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			status = InfStatus.INF_ERROR;
			msg.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		}catch (Exception e) {
			e.printStackTrace();
			msg.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			status = InfStatus.INF_ERROR;
			msg.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		}

		msg.setStatus(status);
		return msg;
	}
	@Override
	public Message queryDataList(Message clientMessage) {
		QueryWrapper<Mapping> entity = new QueryWrapper<Mapping>();
		String clientMsg=null; 
		Page<Mapping>page=null;
		try {
			clientMsg = keyService.getServerDecryptInfo(clientMessage.getMsg());
			JSON jsonObj = JSONUtil.parse(clientMsg);
			String pageStr = JSONUtil.getByPath(jsonObj, IMappingCommon.PAGE_KEY).toString();
			page = JSONUtil.toBean(pageStr, Page.class);
			
			Object objStr = jsonObj.getByPath(IMappingCommon.ORDER);
			Object orderColumn = jsonObj.getByPath(IMappingCommon.SORT);
			boolean serverOrder = true;
			if(objStr != null && orderColumn != null) {
				if(objStr.toString().equalsIgnoreCase("asc")) {
					page.setAsc(orderColumn.toString());
					serverOrder = false;
				}else if(objStr.toString().equalsIgnoreCase("desc")){
					page.setDesc(orderColumn.toString());
					serverOrder = false;
				}
			}
			
			Map<String, Object> obj= (Map<String, Object>) JSONUtil.getByPath(JSONUtil.parse(clientMsg), IMappingCommon.CONDITION_KEY);
			if(obj.size()>0) {
				if(obj.containsKey("NAME") && obj.get("NAME") != null && StringUtils.isNotBlank(obj.get("NAME").toString())) {
					String dmz1String=obj.get("NAME").toString();
					entity.like("name", dmz1String);
				}
				if(obj.containsKey("DMZ8") && obj.get("DMZ8") != null && StringUtils.isNotBlank(obj.get("DMZ8").toString())){
					String dmz8String = obj.get("DMZ8").toString();
					entity.like("dmz8", dmz8String);
				}
				if(obj.containsKey("DATA_TYPE") && obj.get("DATA_TYPE") != null && StringUtils.isNotBlank(obj.get("DATA_TYPE").toString())) {
					entity.eq("DATA_TYPE", obj.get("DATA_TYPE"));
				}
				entity.or(wrapper -> wrapper.allEq(obj, false));
			}
			if(serverOrder) {
				entity.orderByAsc("data_type","name");
			}
			page = (Page<Mapping>) page(page, entity);
			return keyService.serverEncryptData(JSONUtil.toJsonStr(page), page.getRecords().size(),
					clientMessage.getPubKey());
		} catch (UnrecoverableKeyException e) {
			e.printStackTrace();
			return keyService.serverEncryptData(JSONUtil.toJsonStr(e.getMessage()), 0,
					clientMessage.getPubKey());
		} catch (KeyStoreException e) {
			e.printStackTrace();
			return keyService.serverEncryptData(JSONUtil.toJsonStr(e.getMessage()), 0,
					clientMessage.getPubKey());
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			return keyService.serverEncryptData(JSONUtil.toJsonStr(e.getMessage()), 0,
					clientMessage.getPubKey());
		} catch (CertificateException e) {
			e.printStackTrace();
			return keyService.serverEncryptData(JSONUtil.toJsonStr(e.getMessage()), 0,
					clientMessage.getPubKey());
		} catch (IOException e) {
			e.printStackTrace();
			return keyService.serverEncryptData(JSONUtil.toJsonStr(e.getMessage()), 0,
					clientMessage.getPubKey());
		}catch(Exception e) {
			e.printStackTrace();
			return keyService.serverEncryptData(JSONUtil.toJsonStr(e.getMessage()), 0,
					clientMessage.getPubKey());
		}
	}
	@Override
	public Message queryDataDetail(String mappingId,Message clientMessage) {
		Mapping map=getById(mappingId);
		String decryptServerPubKey = null; // 明文服务端的PubKey
		List<Mapping>mapList=Lists.newArrayList();
		mapList.add(map);
		return keyService.serverEncryptData(JSONUtil.toJsonStr(map), 1,
				clientMessage.getPubKey());
	}
	@Override
	public Message deleteOne(String mappingId,Message message) {
		Boolean isResult;
		String decryptServerPubKey = null; // 明文服务端的PubKey
		try {
    	// 将服务端的PubKey解密成明文
     	decryptServerPubKey = keyService.getServerDecryptInfo(message.getPubKey());
     	// 将客户端的PubKey加密成密文
     	String localClientPubKey = keyService.getLocalPubKeyBase64();
     	String cryptePubKey = keyService.getServerEncryptInfo(localClientPubKey, decryptServerPubKey);
     	message.setPubKey(cryptePubKey);
     	
     	isResult=removeById(mappingId);
     	message.setFlag(InfStatus.SAVE_STATUS_SUCESS);
		} catch (UnrecoverableKeyException e) {
			e.printStackTrace();
			message.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			message.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		} catch (KeyStoreException e) {
			e.printStackTrace();
			message.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			message.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
			message.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			message.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		} catch (CertificateException e) {
			e.printStackTrace();
			message.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			message.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		} catch (IOException e) {
			e.printStackTrace();
			message.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			message.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		}catch (Exception e) {
			e.printStackTrace();
			message.setFlag(InfStatus.SAVE_STATUS_EXCEPTION);
			message.setMsg(keyService.getServerEncryptInfo(e.getMessage(), decryptServerPubKey));
		}
     	return message;
	}
}
